package com.lx.thread.MyThread.lx;


import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Description: 线程方法的执行
 * Copyright:   Copyright (c)2019
 * Company:     zefu
 *
 * @author: 张李鑫
 * @version: 1.0
 * Create at:   2021-04-20 14:37:18
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2021-04-20     张李鑫                     1.0         1.0 Version
 */
public class MyThreadTest {

    public static void main(String[] args) {
        overlappingPrint();
    }

    /**
     * <p>
     * 交叉打印a-z 1-26
     *
     * </p>
     *
     * @param
     * @return void
     * @Author zlx
     * @date 2021/4/20
     */
    static Thread t1 = null;
    static Thread t2 = null;
    static Object object=new Object();

    public static void overlappingPrint() {

        t1 = new Thread(() -> {
            synchronized (object) {
                for (char i = 'a'; i < 'z'; i++) {
                    System.out.println(i);

                    try {
                        object.notify();
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                object.notifyAll();
            }

        },"t1");


        t2 = new Thread(() -> {
            synchronized (object) {
                for (int i = 1; i < 26; i++) {
                    System.out.println(i);
                    try {
                        object.notify();
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                object.notifyAll();
            }
        },"t2");

        t1.start();
        t2.start();

    }



    /**
     * 面试题：写一个固定容量同步容器，拥有put和get方法，以及getCount方法，
     * 能够支持2个生产者线程以及10个消费者线程的阻塞调用
     *
     * 使用wait和notify/notifyAll来实现
     *
     * 用while的原因
     * while 只有false了以后才会出循环
     * if不管 true或者false 都会继续向下执行  线程不安全
     *
     * @author mashibing
     */

    private final List <Integer>list= Collections.synchronizedList(new LinkedList<>());

    private  Integer Max=10;

    private static Integer count=0;

    public synchronized Integer get(){

        while (list.size()==0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("数组长度"+list.size());
        Integer integer = list.get(list.size() - 1);
        count--;

        list.remove(list.size()-1);
        System.out.println("数组长度"+list.size()+"移除以后");
        this.notifyAll();
        return integer;
    }

    public synchronized void put(Integer integer){
        while (list.size()==Max){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        list.add(integer);
        System.out.println("数组长度"+list.size()+"put");
        ++count;
        this.notifyAll();
    }

    public static void MyContainer1(){
        MyThreadTest c = new MyThreadTest();
        //启动消费者线程
        for(int i=0; i<10; i++) {
            new Thread(()->{
                for(int j=0; j<5; j++) System.out.println(c.get());
            }, "c" + i).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //启动生产者线程
        for(int i=0; i<2; i++) {
            new Thread(()->{
                for(int j=0; j<25; j++) c.put(j);
            }, "p" + i).start();
        }
    }

}
